<template>
  <div class="text-input" :class="inputClass">
    <input v-model="value" @focusin="onFocus(true)" @focusout="onFocus(false)" class="input" :placeholder="placeholder"
      :type="props.type" />
    <CloseButton @click="clear" />
    <div class="err-message" :class="errMessage ? 'show' : ''">
      <div class="text">{{ errMessage }}</div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { computed, defineProps, onUnmounted, ref } from 'vue'
import CloseButton from './CloseButton.vue'
const props = defineProps({
  type: {
    type: String,
    default: 'text'
  },
  placeholder: {
    type: String,
    default: ''
  },
  showClear: {
    type: Boolean,
    default: false
  },
  confirmBeforeClear: {
    type: Boolean,
    default: true
  },
  modelValue: {
    type: [String, Number],
    default: ''
  },
  errMessage:{
    type: String
  }
})
const value = computed({
  get() {
    return props.modelValue
  },
  set(v) {
    oldValue.value = props.modelValue
    emits('update:modelValue', v)
  }
})
const oldValue = ref<string | number | undefined>(props.modelValue)
const inputClass = computed(() => {
  const c = []
  if (props.showClear && (props.modelValue + '').length > 0) c.push('ready-clear')
  if (isFocus.value) c.push('__focus')
  return c.join(' ')
})
const isFocus = ref(false)
const emits = defineEmits([
  'update:modelValue', //双向绑定
  'focus', //焦点事件 => (isFocus: boolean, value: string)
])
const onFocus = (e: boolean) => {
  emits('focus', e)
  isFocus.value = e
}
const clear = () => {
  if (props.confirmBeforeClear && !confirm('确认要清空内容吗？')) {
    return
  }
  oldValue.value = props.modelValue
}
defineExpose({
  oldValue
})
onUnmounted(() => {
  oldValue.value = undefined
})
</script>
<style lang="scss">
.text-input {
  display: flex;
  align-items: center;
  background: var(--input-color);
  width: 200px;
  height: 30px;
  position: relative;
  border-radius: 5px;

  .input {
    width: 100%;
    left: 0;
    outline: none;
    border: 0;
    border: none;
    font-size: 16px;
    padding: 1px 5px;
    background: none;
    color: var(--text-color);
  }

  .close {
    cursor: pointer;
    position: absolute;
    right: 10px;
    height: 20px;
    width: 20px;
    scale: 0;
    transition: 0.1s;
  }

  .suffix {
    flex-shrink: 1;
    margin-left: 10px;
  }

  .err-message {
    font-size: 13px;
    color: red;
    position: absolute;
    bottom: 0;
    text-align: center;
    margin-bottom: -20px;

    .text {
      transform-origin: center;
      text-align: left;
      width: 100%;
      scale: 0;
      transition: 0.3s;
    }
  }

  .err-message.show {
    .text {
      scale: 1;
      animation: shake 0.3s;
    }
  }

  @keyframes shake {
    0% {
      scale: 0;
      transform: translateX(5px);
    }

    25% {
      scale: 1;
      transform: translateX(0);
    }

    50% {
      scale: 1;
      transform: translateX(5px);
    }

    75% {
      scale: 1;
      transform: translateX(0);
    }

    100% {
      scale: 1;
      transform: translateX(5px);
    }
  }
}

.text-input.ready-clear {
  .input {
    width: calc(100% - 40px);
    right: 30px;
  }

  .close {
    transform-origin: center;
    scale: 1;
    display: block;
    transition: 0.2s;
  }
}
</style>
